package terminal

import (
	"context"
	"time"

	"device-admin/config"
	"device-admin/config/mysql"
	"device-admin/config/redis"
	"device-admin/internal/app/grpc/protoc/devicec"
	"device-admin/internal/define"
	"device-admin/internal/models"
	"device-admin/internal/pkg/ip"

	"192.168.1.75/go-pkg/errorx"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/keepalive"
)

// AutoAddTerminal 自动添加终端
func AutoAddTerminal(robotID, terminalType string) {
	db := mysql.NewDB()
	db.Model(&models.Terminal{}).
		Where(models.Terminal{
			RobotID:      robotID,
			TerminalType: terminalType,
		}).
		Assign(models.Terminal{
			LatestActiveTime: time.Now().Unix(),
		}).
		FirstOrCreate(&models.Terminal{})
}

// UpdateTerminalVersion 更新终端版本
func UpdateTerminalVersion(robotID, terminalType, version string) {
	db := mysql.NewDB()
	db.Model(&models.Terminal{}).
		Where("robot_id = ?", robotID).
		Where("terminal_type = ?", terminalType).
		Updates(map[string]interface{}{
			"current_version": version,
		})
}

// UpdateTerminalActiveTime 更新终端的活跃时间
func UpdateTerminalActiveTime(robotID, terminalType string, time int64) {
	db := mysql.NewDB()
	db.Model(&models.Terminal{}).
		Where("robot_id = ?", robotID).
		Where("terminal_type = ?", terminalType).
		Updates(map[string]interface{}{
			"latest_active_time": time,
		})
}

// SaveSessionIP 记录设备所连接的服务器ip
func SaveSessionServerIP(robotID, terminalType string) {
	// redis键值
	redisKey := define.RedisDeviceSessionIP + robotID + ":" + terminalType
	// 获取本服务ip
	ip := ip.GetLocalIP()
	rdb := redis.NewDB()
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
	defer cancel()
	rdb.Set(ctx, redisKey, ip, 0)
}

// GetSessionServerIP 获取会话的服务IP
func GetSessionServerIP(robotID, terminalType string) string {
	// redis键值
	redisKey := define.RedisDeviceSessionIP + robotID + ":" + terminalType
	rdb := redis.NewDB()
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
	defer cancel()
	ip, _ := rdb.Get(ctx, redisKey).Result()
	return ip
}

// DelSessionServerIP 删除session的服务ip
func DelSessionServerIP(robotID, terminalType string) {
	// redis键值
	redisKey := define.RedisDeviceSessionIP + robotID + ":" + terminalType
	rdb := redis.NewDB()
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
	defer cancel()
	rdb.Del(ctx, redisKey)
}

// SessionServerGrpcClient 设备会话服务的grpc客户端
func SessionServerGrpcClient(robotID, terminalType string) (devicec.DeviceServiceClient, *grpc.ClientConn, error) {
	ip := GetSessionServerIP(robotID, terminalType)
	if ip == "" {
		return nil, nil, errorx.New("节点不在线", -1)
	}
	conn, err := grpc.Dial(
		ip+":"+config.Config.GRPCPort,
		grpc.WithTransportCredentials(insecure.NewCredentials()),
		grpc.WithKeepaliveParams(keepalive.ClientParameters{
			Time:                time.Second * 10,
			Timeout:             time.Second * 10,
			PermitWithoutStream: true,
		}),
	)
	if err != nil {
		return nil, nil, errorx.New("节点不在线", -1)
	}
	cli := devicec.NewDeviceServiceClient(conn)
	return cli, conn, nil
}
